package cate.game.attr;


import cate.common.table.d.GD;
import cate.common.table.d.GDAttr;
import cate.common.table.d.GDCamp;
import easy.java.dev.note.NoteClass;

import java.util.Map;

@NoteClass(value = "战斗属性", detail = "英雄、技能、装备包含的属性都会使用这个类")
public class FightAttr extends Attr<FightAttr> {


    public FightAttr() {}

    public FightAttr(String conf) {
        parse(conf);
    }

    public FightAttr(int attrType, double value) {
        add(attrType, value);
    }


    /** 当前生命 */
    public double hpCur() {
        return getValueDefault(GDAttr.HP_CUR, 0d);
    }

    public void hpCur(double value) {
        raw.put(GDAttr.HP_CUR, value);
    }

    /** 生命(基础生命) */
    private double hp() {return getValueDefault(GDAttr.HP, 0d);}

    public void hp(double value) {
        raw.put(GDAttr.HP,value);
    }

    /** 攻击力(基础攻击)  */
    public double att() {
        return getValueDefault(GDAttr.ATT, 0d);
    }

    public void att(double value) {
        raw.put(GDAttr.ATT, value);
    }

    /** 防御(基础防御)  */
    private double def() {
        return getValueDefault(GDAttr.DEF, 0d);
    }

    public void def(double value) {
        raw.put(GDAttr.DEF, value);
    }

    /** 攻击力附加(万分比值) */
    public double attAR() {return getValueDefault(GDAttr.ATT_AR, 0d);}

    public void attAR(double value) {
        raw.put(GDAttr.ATT_AR, value);
    }

    /** 防御附加(万分比值) */
    public double defAR() {
        return getValueDefault(GDAttr.DEF_AR, 0d);
    }

    public void defAR(double value) {
        raw.put(GDAttr.DEF_AR, value);
    }

    /** 生命附加(万分比值) */
    public double hpAR() {
        return getValueDefault(GDAttr.HP_AR, 0d);
    }

    public void hpAR(double value) {
        raw.put(GDAttr.HP_AR, value);
    }

    /** 速度附加(万分比值) */
    public double speedAR() {
        return getValueDefault(GDAttr.SPEED_AR, 0d);
    }

    public void speedAR(double value) {
        raw.put(GDAttr.SPEED_AR, value);
    }

    /** 速度(基础速度)  */
    private double speed() { return getValueDefault(GDAttr.SPEED, 0d);}

    public void speed(double value) {raw.put(GDAttr.SPEED, value);}

    /** 抗控(万分比值) */
    public double ctrlAnti() { return getValueDefault(GDAttr.CTRL_ANTI, 0d);}

    /** 命中(万分比值) */
    public double hit() {return getValueDefault(GDAttr.HIT, 0d);}

    /** 闪避(万分比值) */
    public double miss() {return getValueDefault(GDAttr.MISS, 0d);}

    /** 暴击率(万分比值) */
    public double strike() {return getValueDefault(GDAttr.STRIKE, 0d);}

    /** 抗暴击率(万分比值) */
    public double strikeAnti() {return getValueDefault(GDAttr.STRIKE_ANTI, 0d);}

    /** 暴伤(万分比值) */
    public double strikeAtt() {return getValueDefault(GDAttr.STRIKE_ATT, 0d);}

    /** 抗暴伤(万分比值) */
    public double strikeAttAnti() {return getValueDefault(GDAttr.STRIKE_ATT_ANTI, 0d);}

    /** 治疗暴击(万分比值) */
    public double healStrike(){return getValueDefault(GDAttr.HEAL_STRIKE, 0d);}

    /** 治疗加成(万分比值) */
    public double healUp() {
        return getValueDefault(GDAttr.HEAL_UP, 0d);
    }

    /** 受疗抑制(万分比值) */
    public double healedDown() {
        return getValueDefault(GDAttr.HEALED_DOWN, 0d);
    }

    /** 物伤(万分比值) */
    public double damageAddPhy() {return getValueDefault(GDAttr.DAMAGE_ADD_PHY, 0d);}

    /** 法伤(万分比值) */
    public double damageAddMagic() {
        return getValueDefault(GDAttr.DAMAGE_ADD_MAGIC, 0d);
    }

    /** 物免(万分比值) */
    public double hurtIgnPhy() {
        return getValueDefault(GDAttr.HURT_IGN_PHY, 0d);
    }

    /** 法免(万分比值) */
    public double hurtIgnMagic() {
        return getValueDefault(GDAttr.HURT_IGN_MAGIC, 0d);
    }

    /** 伤害加成(万分比值) */
    public double damageAdd() {
        return getValueDefault(GDAttr.DAMAGE_ADD, 0d);
    }

    /** 受到伤害减免(万分比值) */
    public double hurtIgn() {return getValueDefault(GDAttr.HURT_IGN, 0d);}

    /** 穿透(万分比值) */
    public double penetrate() {return getValueDefault(GDAttr.PENETRATE, 0d);}

    /** 穿透抵抗(万分比值) */
    public double penetrateDef() {return getValueDefault(GDAttr.PENETRATE_DEF, 0d);}

    /** 格挡几率(万分比值) */
    public double parryRate() {return getValueDefault(GDAttr.PARRY_RATE, 0d);}

    /** 格挡干扰(万分比值) */
    public double parryInterference() {return getValueDefault(GDAttr.PARRY_INTERFERENCE, 0d);}

    /** 格挡豁免(万分比值) */
    public double parryDamageReduce() {return getValueDefault(GDAttr.PARRY_DAMAGE_REDUCE, 0d);}

    /** 神圣伤害 */
    public double hollyDamage() {return getValueDefault(GDAttr.HOLY_DAMAGE, 0d);}

    /** 邪恶保护 */
    public double hollyDamageDef() {return getValueDefault(GDAttr.HOLY_DAMAGE_DEF, 0d);}

    /** pvp对人加伤 */
    public double pvpUp() {return getValueDefault(GDAttr.PVP_UP, 0d);}

    /** pvp对人减伤 */
    public double pvpDown() {return getValueDefault(GDAttr.PVP_DOWN, 0d);}

    /** pve对怪加伤 */
    public double pveUp() {return getValueDefault(GDAttr.PVE_UP, 0d);}

    /** pve对怪减伤 */
    public double pveDown() {return getValueDefault(GDAttr.PVE_DOWN, 0d);}

    /** 对战士伤害加深(万分比值) */
    public double damageAddJ1() { return getValueDefault(GDAttr.DAMAGE_ADD_J1, 0d); }

    /** 对法师伤害加深(万分比值) */
    public double damageAddJ2() { return getValueDefault(GDAttr.DAMAGE_ADD_J2, 0d); }

    /** 对坦克伤害加深(万分比值) */
    public double damageAddJ3() { return getValueDefault(GDAttr.DAMAGE_ADD_J3, 0d); }

    /** 对辅助伤害加深(万分比值) */
    public double damageAddJ4() { return getValueDefault(GDAttr.DAMAGE_ADD_J4, 0d); }

    /** 控制(万分比值) */
    public double ctrl() {return getValueDefault(GDAttr.CTRL, 0d);}

    /** 吸血绝对值 */
    public double suckVal() {return getValueDefault(GDAttr.SUCK_VAL, 0d);}

    /** 对战士伤害减免(万分比值) */
    public double hurtIgnJ1() { return getValueDefault(GDAttr.HURT_IGN_J1, 0d);}

    /** 对法师伤害减免(万分比值) */
    public double hurtIgnJ2() { return getValueDefault(GDAttr.HURT_IGN_J2, 0d); }

    /** 对坦克伤害减免(万分比值) */
    public double hurtIgnJ3() {
        return getValueDefault(GDAttr.HURT_IGN_J3, 0d);
    }

    /** 对辅助伤害减免(万分比值) */
    public double hurtIgnJ4() {
        return getValueDefault(GDAttr.HURT_IGN_J4, 0d);
    }

    /** 物理吸血(万分比值) */
    public double suckPhy() {
        return getValueDefault(GDAttr.SUCK_PHY, 0d);
    }

    /** 法术吸血(万分比值) */
    public double suckMagic() {
        return getValueDefault(GDAttr.SUCK_MAGIC, 0d);
    }

    /** 灵能攻击 */
    private double psyAtt(){return getValueDefault(GDAttr.PSY_ATT, 0d);}

    /** 灵能防御 */
    private double psyDef(){return getValueDefault(GDAttr.PSY_DEF, 0d);}

    /** 灵能强化 */
    public double psyUp(){return getValueDefault(GDAttr.PSY_UP, 0d);}

    /** 灵能抵抗 */
    public double psyRes(){return getValueDefault(GDAttr.PSY_RES, 0d);}

    /** 对水系加伤 */
    public double damageAddC1(){return getValueDefault(GDAttr.DAMAGE_ADD_C1, 0d);}
    /** 对火系加伤 */
    public double damageAddC2(){return getValueDefault(GDAttr.DAMAGE_ADD_C2, 0d);}
    /** 对木系加伤 */
    public double damageAddC3(){return getValueDefault(GDAttr.DAMAGE_ADD_C3, 0d);}
    /** 对土系加伤 */
    public double damageAddC4(){return getValueDefault(GDAttr.DAMAGE_ADD_C4, 0d);}
    /** 对光系加伤 */
    public double damageAddC5(){return getValueDefault(GDAttr.DAMAGE_ADD_C5, 0d);}
    /** 对暗系加伤 */
    public double damageAddC6(){return getValueDefault(GDAttr.DAMAGE_ADD_C6, 0d);}

    /** 灵能攻击加成 */
    private double psyAttAR(){return getValueDefault(GDAttr.PSY_ATT_AR, 0d);}
    /** 灵能防御加成 */
    private double psyDefAR(){return getValueDefault(GDAttr.PSY_DEF_AR, 0d);}

    /** 对水系免伤 */
    public double hurtIgnC1(){return getValueDefault(GDAttr.HURT_IGN_C1, 0d);}
    /** 对火系免伤 */
    public double hurtIgnC2(){return getValueDefault(GDAttr.HURT_IGN_C2, 0d);}
    /** 对木系免伤 */
    public double hurtIgnC3(){return getValueDefault(GDAttr.HURT_IGN_C3, 0d);}
    /** 对土系免伤 */
    public double hurtIgnC4(){return getValueDefault(GDAttr.HURT_IGN_C4, 0d);}
    /** 对光系免伤 */
    public double hurtIgnC5(){return getValueDefault(GDAttr.HURT_IGN_C5, 0d);}
    /** 对暗系免伤 */
    public double hurtIgnC6(){return getValueDefault(GDAttr.HURT_IGN_C6, 0d);}

    /** 最终增伤 */
    public double pvpFinalDamageAdd(){return getValueDefault(GDAttr.PVP_FINAL_DAMAGE_ADD, 0d);}

    /** 最终减伤 */
    public double pvpFinalHurtIgn(){return getValueDefault(GDAttr.PVP_FINAL_HURT_IGN, 0d);}

    /** 水攻 */
    private double elementC1Att(){return getValueDefault(GDAttr.ELEMENT_C1_ATT, 0d);}
    /** 火攻 */
    private double elementC2Att(){return getValueDefault(GDAttr.ELEMENT_C2_ATT, 0d);}
    /** 木攻 */
    private double elementC3Att(){return getValueDefault(GDAttr.ELEMENT_C3_ATT, 0d);}
    /** 土攻 */
    private double elementC4Att(){return getValueDefault(GDAttr.ELEMENT_C4_ATT, 0d);}
    /** 光攻 */
    private double elementC5Att(){return getValueDefault(GDAttr.ELEMENT_C5_ATT, 0d);}
    /** 暗攻 */
    private double elementC6Att(){return getValueDefault(GDAttr.ELEMENT_C6_ATT, 0d);}


    /** 水防 */
    private double elementC1Def(){return getValueDefault(GDAttr.ELEMENT_C1_DEF, 0d);}
    /** 火防 */
    private double elementC2Def(){return getValueDefault(GDAttr.ELEMENT_C2_DEF, 0d);}
    /** 木防 */
    private double elementC3Def(){return getValueDefault(GDAttr.ELEMENT_C3_DEF, 0d);}
    /** 土防 */
    private double elementC4Def(){return getValueDefault(GDAttr.ELEMENT_C4_DEF, 0d);}
    /** 光防 */
    private double elementC5Def(){return getValueDefault(GDAttr.ELEMENT_C5_DEF, 0d);}
    /** 暗防 */
    private double elementC6Def(){return getValueDefault(GDAttr.ELEMENT_C6_DEF, 0d);}

    /** 水攻加成 */
    private double elementC1DamageAdd(){return getValueDefault(GDAttr.ELEMENT_C1_DAMAGE_ADD, 0d);}
    /** 火攻加成 */
    private double elementC2DamageAdd(){return getValueDefault(GDAttr.ELEMENT_C2_DAMAGE_ADD, 0d);}
    /** 木攻加成 */
    private double elementC3DamageAdd(){return getValueDefault(GDAttr.ELEMENT_C3_DAMAGE_ADD, 0d);}
    /** 土攻加成 */
    private double elementC4DamageAdd(){return getValueDefault(GDAttr.ELEMENT_C4_DAMAGE_ADD, 0d);}
    /** 光攻加成 */
    private double elementC5DamageAdd(){return getValueDefault(GDAttr.ELEMENT_C5_DAMAGE_ADD, 0d);}
    /** 暗攻加成 */
    private double elementC6DamageAdd(){return getValueDefault(GDAttr.ELEMENT_C6_DAMAGE_ADD, 0d);}


    /** 水抗 */
    private double elementC1Ign(){return getValueDefault(GDAttr.ELEMENT_C1_IGN, 0d);}
    /** 火抗 */
    private double elementC2Ign(){return getValueDefault(GDAttr.ELEMENT_C2_IGN, 0d);}
    /** 木抗 */
    private double elementC3Ign(){return getValueDefault(GDAttr.ELEMENT_C3_IGN, 0d);}
    /** 土抗 */
    private double elementC4Ign(){return getValueDefault(GDAttr.ELEMENT_C4_IGN, 0d);}
    /** 光抗 */
    private double elementC5Ign(){return getValueDefault(GDAttr.ELEMENT_C5_IGN, 0d);}
    /** 暗抗 */
    private double elementC6Ign(){return getValueDefault(GDAttr.ELEMENT_C6_IGN, 0d);}





    /** 总的hp (最低不会低于1) */
    public double hpTotal() {return Math.max(1,hp() * (GD.W_10000_0 + hpAR()) / GD.W_10000_0);}
    /** 总的攻击 */
    public double attTotal() {
        return (att() * (GD.W_10000_0 + attAR()) / GD.W_10000_0);
    }
    /** 总的防御 */
    public double defTotal() {
        return (def() * (GD.W_10000_0 + defAR()) / GD.W_10000_0);
    }
    /** 总的速度 */
    public double speedTotal() {return (speed() * (GD.W_10000_0 + speedAR()) / GD.W_10000_0);}

    /** 总的灵能攻击 */
    public double psyAttTotal() {
        return (psyAtt() * (GD.W_10000_0 + psyAttAR()) / GD.W_10000_0);
    }
    /** 总的灵能防御 */
    public double psyDefTotal() { return (psyDef() * (GD.W_10000_0 + psyDefAR()) / GD.W_10000_0);}

    /** 总的水攻 */
    private double elementC1AttTotal(){return elementC1Att() * (GD.W_10000_0 + elementC1DamageAdd()) / GD.W_10000_0;}
    /** 总的火攻 */
    private double elementC2AttTotal(){return elementC2Att() * (GD.W_10000_0 + elementC2DamageAdd()) / GD.W_10000_0;}
    /** 总的木攻 */
    private double elementC3AttTotal(){return elementC3Att() * (GD.W_10000_0 + elementC3DamageAdd()) / GD.W_10000_0;}
    /** 总的土攻 */
    private double elementC4AttTotal(){return elementC4Att() * (GD.W_10000_0 + elementC4DamageAdd()) / GD.W_10000_0;}
    /** 总的光攻 */
    private double elementC5AttTotal(){return elementC5Att() * (GD.W_10000_0 + elementC5DamageAdd()) / GD.W_10000_0;}
    /** 总的暗攻 */
    private double elementC6AttTotal(){return elementC6Att() * (GD.W_10000_0 + elementC6DamageAdd()) / GD.W_10000_0;}

    /** 总的元素攻击 */
    public double elementAttTotal(byte camp) {
        switch (camp) {
            case GDCamp.Type.C1:
                return elementC1AttTotal();
            case GDCamp.Type.C2:
                return elementC2AttTotal();
            case GDCamp.Type.C3:
                return elementC3AttTotal();
            case GDCamp.Type.C4:
                return elementC4AttTotal();
            case GDCamp.Type.C5:
                return elementC5AttTotal();
            case GDCamp.Type.C6:
                return elementC6AttTotal();
            default:
                return 0d;
        }
    }

    /** 元素防御 */
    public double elementDef(byte camp){
        switch (camp) {
            case GDCamp.Type.C1:
                return elementC1Def();
            case GDCamp.Type.C2:
                return elementC2Def();
            case GDCamp.Type.C3:
                return elementC3Def();
            case GDCamp.Type.C4:
                return elementC4Def();
            case GDCamp.Type.C5:
                return elementC5Def();
            case GDCamp.Type.C6:
                return elementC6Def();
            default:
                return 0d;
        }
    }

    /** 元素抗性 */
    public double elementIgn(byte camp){
        switch (camp) {
            case GDCamp.Type.C1:
                return elementC1Ign();
            case GDCamp.Type.C2:
                return elementC2Ign();
            case GDCamp.Type.C3:
                return elementC3Ign();
            case GDCamp.Type.C4:
                return elementC4Ign();
            case GDCamp.Type.C5:
                return elementC5Ign();
            case GDCamp.Type.C6:
                return elementC6Ign();
            default:
                return 0d;
        }
    }


    /** 物连概率浮动(万分比值)*/
    public double floatDoubleActPhy(){ return getValueDefault(GDAttr.FLOAT_DOUBLE_ACT_PHY, 0d);}

    /** 法连概率浮动(万分比值)*/
    public double floatDoubleActMagic(){
        return getValueDefault(GDAttr.FLOAT_DOUBLE_ACT_MAGIC, 0d);
    }

    /** 连击概率*/
    public double getDoubleActChance(boolean isPhy){
        if(isPhy){
            return floatDoubleActPhy();
        }
        return floatDoubleActMagic();
    }

    /** 当前生命值比例 */
    public int hpCurRate() {
        double cur = hpCur();
        double hp = hpTotal();
        if (hp <= 0) {
            hp = GD.W_10000;
        }
        int rate = (int) (cur / hp * GD.W_10000_0);
        return rate > GD.W_10000 ? GD.W_10000 : rate;
    }

    /** 损失血量比例 */
    public int hpLossRate() {
        return GD.W_10000 - hpCurRate();
    }

    /** 损失血量 */
    public double hpLoss() {
        return hpTotal() - hpCur();
    }


    public double getTotalValue(int type){return getTotalValue(type,GD.DOUBLE_0);}

    /** 获得综合计算的值，生命值、攻击力、防御力和速度这种，都是有附加万分比的，都要合计起来 */
    public double getTotalValue(int type, double defaultValue) {
        switch (type) {
            case GDAttr.HP:
                return hpTotal();
            case GDAttr.ATT:
                return attTotal();
            case GDAttr.DEF:
                return defTotal();
            case GDAttr.SPEED:
                return speedTotal();
            case GDAttr.V_HP_LEFT_RATE:
                return hpCurRate();
            case GDAttr.V_HP_LOSS_RATE:
                return hpLossRate();
            case GDAttr.V_HP_LEFT:
                return hpCur();
            case GDAttr.V_HP_LOSS:
                return hpLoss();
            case GDAttr.PSY_ATT:
                return psyAttTotal();
            case GDAttr.PSY_DEF:
                return psyDefTotal();
            default:
                return getValueDefault(type, defaultValue);
        }
    }

    /** 深拷贝一份数据 */
    @Override
    public FightAttr copy() {
        FightAttr cp = new FightAttr();
        super.copy(cp);
        return cp;
    }

    @Override
    protected String getKeyName(Integer k) {
        return GDAttr.getKeyName(k);
    }

    /** 构建一阶属性 */
    public FightAttr buildS1() {
        FightAttr s1 = this.copy();
        s1.hpAR(0);
        s1.attAR(0);
        s1.defAR(0);
        s1.speedAR(0);
        return s1;
    }

    /** 构建二阶属性 */
    public FightAttr buildS2() {
        FightAttr s2 = new FightAttr();
        s2.hpAR(this.hpAR());
        s2.attAR(this.attAR());
        s2.defAR(this.defAR());
        s2.speedAR(this.speedAR());
        return s2;
    }

    /** 根据百分比加成计算属性 */
    public FightAttr addAndCalS2(FightAttr s2) {
        this.hp(HAR(this.hp(), s2.hpAR()));
        this.att(HAR(this.att(), s2.attAR()));
        this.def(HAR(this.def(), s2.defAR()));
        this.speed(HAR(this.speed(), s2.speedAR()));
        return this;
    }

    private double HAR(double value, double ar) {
        return value * (GD.W_10000_0 + ar) / GD.W_10000_0;
    }

    /**
     * 构建属性code
     * @return
     */
    public String buildCode(){
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<Integer, Double> entry : raw.entrySet()) {
            sb.append(entry.getKey());
            sb.append(":");
            sb.append(entry.getValue());
            sb.append("#");
        }
        sb.deleteCharAt(sb.lastIndexOf("#"));
        return sb.toString();
    }

    /**
     * 包含生命相关属性
     * @return
     */
    public boolean containHpAttr(){
        return raw.containsKey(GDAttr.HP)||raw.containsKey(GDAttr.HP_AR);
    }

    public void clear(){
        raw.clear();
    }

    //移除指定属性
    public void remove(int attr){
        raw.remove(attr);
    }
}
